package com.liveinstars.post.application.controller.content.api;

import com.baidu.unbiz.easymapper.MapperFactory;
import com.liveinstars.api.post.dto.BaseCommentDTO;
import com.liveinstars.api.post.dto.BaseCommentVO;
import com.liveinstars.api.post.dto.PostCommentParam;
import com.liveinstars.api.post.dto.PostDetailDto;
import com.liveinstars.api.post.facade.IPostsApi;
import com.liveinstars.common.utils.JsonUtil;
import com.liveinstars.post.business.model.entity.Post;
import com.liveinstars.post.business.model.enums.PostStatus;
import com.liveinstars.post.business.model.params.BaseCommentParam;
import com.liveinstars.post.business.model.vo.PostDetailVO;
import com.liveinstars.post.business.model.vo.PostListVO;
import com.liveinstars.post.business.service.OptionService;
import com.liveinstars.post.business.service.PostCommentService;
import com.liveinstars.post.business.service.PostService;
import com.onepiece.shipelves.common.Result;
import com.onepiece.shipelves.common.enums.SystemExceptionEnum;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.SortDefault;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.springframework.data.domain.Sort.Direction.DESC;


/**
 * 活动的id也可以复用post的评论点赞和收藏，因为他们的id是是由同一redis生成的
 */
@RestController
public class PostOpenController implements IPostsApi {

    private final PostService postService;

    private final PostCommentService postCommentService;

    private final OptionService optionService;

    public PostOpenController(PostService postService,
                              PostCommentService postCommentService,
                              OptionService optionService) {
        this.postService = postService;
        this.postCommentService = postCommentService;
        this.optionService = optionService;
    }


    @Override
    public Map<Integer, List<PostDetailDto>> listByInterestHotPost(@RequestParam(value = "interestId") List<Integer> interestIds) {

        Sort sort = new Sort(DESC, "createTime");
        Pageable page = PageRequest.of(0, 3, sort);
        Map<Integer, List<PostDetailDto>> map = new HashMap<>();
        for (Integer interestId :
                interestIds) {
            Page<Post> postPage = postService.pageByInterest(PostStatus.PUBLISHED, page, interestId);
            Page<PostListVO> postListVOS = postService.convertToListVo(postPage, 0);
            MapperFactory.getCopyByRefMapper().mapClass(PostListVO.class, PostDetailDto.class).register();
            List<PostDetailDto> postDetailDtos = postListVOS.stream().map(p -> MapperFactory.getCopyByRefMapper().map(p,
                    PostDetailDto.class)).collect(Collectors.toList());
            map.put(interestId, postDetailDtos);
        }

        return map;
    }


    @Override
    public PostDetailDto getBy(@PathVariable("postId") Integer postId) {
        PostDetailVO postDetailVO = postService.convertToDetailVo(postService.getById(postId));

        PostDetailDto detailDto = MapperFactory.getCopyByRefMapper().mapClass(PostDetailVO.class, PostDetailDto.class).register()
                .map(postDetailVO, PostDetailDto.class);
        return detailDto;

    }

    @Override
    public Boolean isLike(@PathVariable("postId") Integer postId, @RequestHeader("uid") Integer userId) {
        if (userId == null || userId == 0) {
            return false;
        }

        return postService.isLike(postId, userId);
    }


    @Override
    public Boolean like(@PathVariable("postId") Integer postId, @RequestHeader("uid") Integer userId) {
        if (userId == null || userId == 0) {
            return false;
        }

        postService.increaseLike(postId, userId);
        return true;
    }


    @Override
    public Boolean unLike(@PathVariable("postId") Integer postId, @RequestHeader("uid") Integer userId) {
        if (userId == null || userId == 0) {
            return false;
        }
        postService.decreaseLike(postId, userId);
        return true;
    }

    @Override
    public Boolean collect(@PathVariable("postId") Integer postId, @RequestHeader("uid") Integer userId) {
        if (userId == null || userId == 0) {
            return false;
        }
        postService.collectPost(postId, userId);
        return true;
    }


    @Override
    public Boolean unCollect(@PathVariable("postId") Integer postId, @RequestHeader("uid") Integer userId) {
        if (userId == null || userId == 0) {
            return false;
        }
        postService.unCollectPost(postId, userId);
        return true;
    }

    @Override
    public BaseCommentDTO comment(@RequestBody PostCommentParam postCommentParam) {

        BaseCommentParam map = MapperFactory.getCopyByRefMapper().mapClass(PostCommentParam.class, BaseCommentParam.class).register().map(postCommentParam, BaseCommentParam.class);
        postCommentService.validateCommentBlackListStatus();

        // Escape content
        postCommentParam.setContent(HtmlUtils.htmlEscape(postCommentParam.getContent(), StandardCharsets.UTF_8.displayName()));
        com.liveinstars.post.business.model.dto.BaseCommentDTO baseCommentDTO = postCommentService.convertTo(postCommentService.createBy(map));
        return MapperFactory.getCopyByRefMapper().mapClass(com.liveinstars.post.business.model.dto.BaseCommentDTO.class, BaseCommentDTO.class).register().map(baseCommentDTO, BaseCommentDTO.class);
    }

    @Override
    public Page<BaseCommentVO> listCommentsTree(@SortDefault(sort = "createTime", direction = DESC) Sort sort, @PathVariable("postId") Integer postId,
                                                @RequestParam(name = "page", required = false, defaultValue = "0") int page
    ) {

        Page<com.liveinstars.post.business.model.vo.BaseCommentVO> baseCommentVOS = postCommentService.pageVosBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort));

        Page map = MapperFactory.getCopyByRefMapper().mapClass(Page.class, Page.class).register().map(baseCommentVOS, Page.class);
        return map;
    }

//    @Override
//    public BaseCommentDTO activityComment(@RequestBody PostCommentParam postCommentParam) {
//
//        BaseCommentParam map = MapperFactory.getCopyByRefMapper().mapClass(PostCommentParam.class, BaseCommentParam.class).register().map(postCommentParam, BaseCommentParam.class);
//        postCommentService.validateCommentBlackListStatus();
//
//        // Escape content
//        postCommentParam.setContent(HtmlUtils.htmlEscape(postCommentParam.getContent(), StandardCharsets.UTF_8.displayName()));
//        com.liveinstars.post.business.model.dto.BaseCommentDTO baseCommentDTO = postCommentService.convertTo(postCommentService.createBy(map));
//        return MapperFactory.getCopyByRefMapper().mapClass(com.liveinstars.post.business.model.dto.BaseCommentDTO.class, BaseCommentDTO.class).register().map(baseCommentDTO, BaseCommentDTO.class);
//    }
//
//    @Override
//    public String listActivityCommentsTree(@SortDefault(sort = "createTime", direction = DESC) Sort sort, @PathVariable("postId") Integer postId,
//                                           @RequestParam(name = "page", required = false, defaultValue = "0") int page
//    ) {
//
//        Page<com.liveinstars.post.business.model.vo.BaseCommentVO> baseCommentVOS = postCommentService.pageVosBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
//
//        return JsonUtil.toJson(baseCommentVOS);
//    }
}
